﻿using Xejen.Ipc.Framework.Flows;
using Xejen.Ipc.Framework.Steps;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;

namespace Xejen.Ipc.Framework.Controllers
{
    /// <summary>
    /// 表示流控制器<see cref="IController{TData}"/>的构造器
    /// </summary>
    /// <typeparam name="TData"><inheritdoc cref="IFlow{TData}" path="/typeparam[@name='TData']"/></typeparam>
    /// <creator>marc</creator>
    public interface IControllerBuilder<TData>
        where TData : new()
    {
        /// <summary>
        /// 顺序控制：顺序执行下一个控制器<see cref="IController{TData}"/>
        /// </summary>
        /// <param name="stepBuilders">构建步骤<see cref="IStep{TData}"/></param>
        /// <returns></returns>
        IControllerBuilder<TData> Then(params Func<IStepProvider<TData>, IStep<TData>>[] stepBuilders);

        /// <summary>
        /// 任意控制：只要集合中的任意其中一个步骤<see cref="IStep{TData}"/>执行完成，即可流转到下一个控制器<see cref="IController{TData}"/>
        /// </summary>
        /// <param name="stepBuilders">构建多个步骤<see cref="IStep{TData}"/></param>
        /// <returns></returns>
        IControllerBuilder<TData> Any(params Func<IStepProvider<TData>, IStep<TData>>[] stepBuilders);

        /// <summary>
        /// 全部控制：集合中的所有步骤<see cref="IStep{TData}"/>均需要完成，才允许流转到下一个控制器<see cref="IController{TData}"/>
        /// </summary>
        /// <param name="stepBuilders">构建多个步骤<see cref="IStep{TData}"/></param>
        /// <returns></returns>
        IControllerBuilder<TData> All(params Func<IStepProvider<TData>, IStep<TData>>[] stepBuilders);

        /// <summary>
        /// 条件控制：条件满足时才会执行此控制器中的步骤<see cref="IStep{TData}"/>，否则越过本环节进入下一个控制器<see cref="IController{TData}"/>
        /// </summary>
        /// <param name="stepBuilders">构建步骤<see cref="IStep{TData}"/></param>
        /// <param name="condition">控制器的触发条件</param>
        /// <param name="else">当控制器的触发条件<paramref name="condition"/>不满足时，要执行的逻辑</param>
        /// <returns></returns>
        IControllerBuilder<TData> If(Func<TData, bool> condition, Action<TData> @else = null, params Func<IStepProvider<TData>, IStep<TData>>[] stepBuilders);

        /// <summary>
        /// 构建控制流<see cref="IFlow{TData}"/>
        /// </summary>
        /// <param name="flowName"><inheritdoc cref="IFlow{TData}.Name" path="/summary"/></param>
        /// <param name="parent">父流程</param>
        /// <returns></returns>
        IFlow<TData> Build(string flowName, IFlow<TData> parent = null);
    }
}
